<template>
  <el-dialog
    v-model="visible"
    title="接口测试"
    width="1100px"
    :close-on-press-escape="false"
    :close-on-click-modal="false"
    append-to-body
    destroy-on-close
    @close="dialogClosed"
  >
    <div class="flex flex-row p-2" style="height: 600px">
      <div class="w-1/2 pr-2">
        <div class="font-bold mb-2">API接口名称：{{ currentItem.name }}</div>
        <div class="mb-2">
          <el-link type="primary" @click="showScript(currentItem.sql, '查询SQL')">
            SQL模板：
          </el-link>
        </div>
        <div class="mb-2 flex flex-row items-center">
          <div class="mr-2">转换器编码：</div>
          <el-select
            v-model="transformerId"
            clearable
            filterable
            size="small"
            @change="initUrlParams"
            style="width: 200px"
            class="mr-2"
          >
            <el-option
              v-for="item in transformerList"
              :key="item.id"
              :value="item.id"
              :label="item.name"
            />
          </el-select>
          <el-button type="primary" size="small" @click="transformerShow = true">
            自定义
          </el-button>
        </div>
        <div class="mb-2">
          <el-input v-model.trim="url">
            <template #prepend>
              <el-select v-model="method" style="width: 80px">
                <el-option value="get" label="get" />
                <el-option value="post" label="post" />
              </el-select>
            </template>
            <template #append>
              <el-button
                type="primary"
                icon="Position"
                :loading="loading"
                v-hasPermi="['web:db:api:apiDetail:test']"
                @click="send"
              >
                发送
              </el-button>
            </template>
          </el-input>
        </div>
        <div class="font-bold mb-2">API请求参数：</div>
        <el-tabs v-model="queryType">
          <el-tab-pane label="Body" name="Body">
            <CodeEditor v-model:value="bodyData" height="375px" />
          </el-tab-pane>
          <el-tab-pane label="Params" name="Params">
            <div class="mb-2">
              <el-button type="primary" @click="addParams"> 添加参数 </el-button>
            </div>
            <el-table :data="paramsData" @selection-change="handleSelectionChange" height="335">
              <el-table-column type="selection" width="40" align="center" />
              <el-table-column label="参数名" prop="label" align="center" width="120">
                <template #default="{ row }">
                  <el-input v-model="row.label" size="small" clearable @change="initUrlParams" />
                </template>
              </el-table-column>
              <el-table-column label="参数值" prop="value" align="center" width="130">
                <template #default="{ row }">
                  <el-input v-model="row.value" size="small" clearable @change="initUrlParams" />
                </template>
              </el-table-column>
              <el-table-column label="参数描述" prop="remark" align="center">
                <template #default="{ row }">
                  <el-input v-model="row.remark" size="small" clearable />
                </template>
              </el-table-column>
              <el-table-column label="操作" prop="remark" align="center" width="70">
                <template #default="{ $index }">
                  <el-button type="primary" size="small" text @click="deleteParams($index)">
                    删除
                  </el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-tab-pane>
        </el-tabs>
      </div>
      <div class="w-1/2">
        <div class="font-bold mb-1">API接口返回结果：</div>
        <CodeEditor v-model:value="testResult" height="560px" />
      </div>
    </div>

    <script-view v-model="scriptShow" :title="scriptTitle" :content="scriptContent" />

    <detail-transformer v-model="transformerShow" @success="getTransformer" />
  </el-dialog>
</template>

<script setup>
  import { ref, computed, watch, defineProps, defineEmits } from 'vue';
  import { pageDataTransformer } from '@/api/web/db/transformer';
  import { dataApi } from '@/api/web/db/api/api-detail';
  import { CodeEditor } from '@/components/CodeEditor';
  import DetailTransformer from '../../transformer/components/detail-transformer';
  import ScriptView from './script-view';
  import beautifier from 'js-beautify';

  const props = defineProps({
    modelValue: {
      type: Boolean,
      default: false,
    },
    currentItem: {
      type: Object,
      default: () => ({}),
    },
  });

  const emits = defineEmits(['update:modelValue']);

  const transformerShow = ref(false);
  const scriptTitle = ref('');
  const scriptShow = ref(false);
  const scriptContent = ref('');
  const transformerList = ref([]);
  const method = ref('');
  const url = ref('');
  const queryType = ref('Body');
  const bodyData = ref('');
  const paramsData = ref([]);
  const transformerId = ref('');
  const testResult = ref('');
  const items = ref([]);
  const loading = ref(false);

  const visible = computed({
    set(val) {
      emits('update:modelValue', val);
    },
    get() {
      return props.modelValue;
    },
  });

  watch(visible, (v) => {
    if (v) {
      method.value = props.currentItem.httpMethod;
      url.value = props.currentItem.path;

      const obj = {};
      const list = [
        { remark: '当前页码', label: 'pageNum', value: 1 },
        { remark: '分页数量', label: 'pageSize', value: 10 },
      ];

      props.currentItem?.apiParams?.forEach((item) => {
        obj[item.name] = item?.isList === '是' ? [] : item?.example;
        list.push({
          remark: item.remark,
          label: item.name,
          value: item?.isList === '是' ? [] : item?.example,
        });
      });

      bodyData.value = JSON.stringify(obj);
      paramsData.value = list;
      testResult.value = '';
      items.value = [];

      getTransformer();
    }
  });

  function addParams() {
    const obj = {
      remark: null,
      label: null,
      value: null,
    };
    paramsData.value.push(obj);
  }

  function deleteParams(index) {
    paramsData.value.splice(index, 1);
  }

  function handleSelectionChange(selection) {
    items.value = selection.map((item) => item);
    initUrlParams();
  }

  function initUrlParams() {
    let str = transformerId.value ? `transformerId=${transformerId.value}&` : '';
    items.value.forEach((item) => {
      if (item.value) {
        str += `${item.label}=${item.value}&`;
      }
    });
    url.value = props.currentItem.path + '?' + str;
  }

  function send() {
    loading.value = true;
    dataApi(
      method.value,
      url.value,
      JSON.parse(bodyData.value || '{}'),
      props.currentItem.encrypt,
      props.currentItem.encryptAlgorithm,
      props.currentItem.encryptKey,
    )
      .then((res) => {
        testResult.value = beautifier(JSON.stringify(res.data) || '', {
          indent_size: 2,
          space_in_empty_paren: true,
        });
      })
      .finally(() => {
        loading.value = false;
      });
  }

  function showScript(content, title) {
    scriptContent.value = content;
    scriptTitle.value = title;
    scriptShow.value = true;
  }

  function getTransformer() {
    pageDataTransformer({ pageNum: 1, pageSize: 9999 }).then((res) => {
      transformerList.value = res.data.records;
    });
  }

  function dialogClosed() {
    transformerShow.value = false;
    scriptTitle.value = '';
    scriptShow.value = false;
    scriptContent.value = '';
    transformerList.value = [];
    method.value = '';
    url.value = '';
    queryType.value = 'Body';
    bodyData.value = '';
    paramsData.value = [];
    transformerId.value = '';
    testResult.value = '';
    items.value = [];
    loading.value = false;
  }
</script>

<style scoped lang="scss"></style>
